package com.example.config;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.alibaba.cloud.nacos.NacosDiscoveryProperties;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import jakarta.annotation.PostConstruct;
import org.springframework.core.env.Environment;

import java.util.List;


@Data
@Configuration
@Slf4j
@ConfigurationProperties(prefix = "snowflake-config")
public class SnowflakeConfig {
    private Long workerId;
    private Long datacenterId;
    private static Snowflake snowflake;

    @Autowired
    private SnowflakeProperties snowflakeProperties;

    @Autowired
    private NacosDiscoveryProperties nacosDiscoveryProperties;

    @Autowired
    private Environment environment;

    /**
     * @PostConstruct 标记的方法保证在所有依赖注入完成后执行，
     * 这意味着 workerId 和 datacenterId 已经被正确地从配置文件中读取并赋值给相应的字段，
     * 从而可以安全地使用它们来初始化 Snowflake 实例
     */
    @PostConstruct
    public void init() {
        String key = nacosDiscoveryProperties.getIp() + ":" + environment.getProperty("server.port");
        List<SnowflakeProperties.ServerConfig> lists = snowflakeProperties.getLists();
        for (SnowflakeProperties.ServerConfig list : lists) {
            if (key.equals(list.getHost() + ":" + list.getPort())){
                workerId = list.getWorkerId();
                datacenterId = list.getDatacenterId();
                break;
            }
        }

        if (workerId == null || datacenterId == null) {
            log.error("key: {}", key);
            throw new IllegalArgumentException("无效配置");
        }

        if (workerId < 0 || workerId > 1023 || datacenterId < 0 || datacenterId > 31) {
            throw new IllegalArgumentException("Invalid workerId or datacenterId");
        }
        snowflake = IdUtil.getSnowflake(workerId, datacenterId);
    }

    @Bean
    public Snowflake getSnowflake() {
        return snowflake;
    }

    public long nextId() {
        return snowflake.nextId();
    }
}